﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Engine;
using NHibernate.Type;
using NHibernate.UserTypes;
using System;
using System.Data;


namespace epicenter2010.NH.Customisation.UserTypes
{
	/// <summary>
	/// bstack @ 07/06/2010
	/// References composite user type
	/// </summary>
	public class CompositeReferencesType : ICompositeUserType
	{
		/// <summary>
		/// Get Property value
		/// </summary>
		/// <param name="component"></param>
		/// <param name="property"></param>
		/// <returns></returns>
		public object GetPropertyValue(object component, int property)
		{
			var _references = (epicenter2010.NH.Customisation.UserTypes.References)component;

			if (property == 0)
				return _references.Primary;
			if (property == 1)
				return _references.Secondary;
			
			return _references.Tertiary;
		}


		/// <summary>
		/// Set property value
		/// </summary>
		/// <param name="component"></param>
		/// <param name="property"></param>
		/// <param name="value"></param>
		public void SetPropertyValue(object component, int property, object value)
		{
			throw new Exception("Immutable!");
		}


		/// <summary>
		/// Equals
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		public new bool Equals(object x, object y)
		{
			if (object.ReferenceEquals(x, y)) return true;
			if (x == null || y == null) return false;
			return x.Equals(y);
		}


		/// <summary>
		/// Get hash code
		/// </summary>
		/// <param name="x"></param>
		/// <returns></returns>
		public int GetHashCode(object x)
		{
			return x.GetHashCode();
		}


		/// <summary>
		/// Null safe get
		/// </summary>
		/// <param name="dr"></param>
		/// <param name="names"></param>
		/// <param name="session"></param>
		/// <param name="owner"></param>
		/// <returns></returns>
		public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
		{
			string _primary = null;
			string _secondary = null;
			string _tertiary = null;


			object obj0 = NHibernateUtil.String.NullSafeGet(dr, names[0]);
			object obj1 = NHibernateUtil.String.NullSafeGet(dr, names[1]);
			object obj2 = NHibernateUtil.String.NullSafeGet(dr, names[2]);

			return new epicenter2010.NH.Customisation.UserTypes.References(_primary, _secondary, _tertiary);
		}


		/// <summary>
		/// Null safe set
		/// </summary>
		/// <param name="cmd"></param>
		/// <param name="value"></param>
		/// <param name="index"></param>
		/// <param name="session"></param>
		public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session)
		{
			var _references = (epicenter2010.NH.Customisation.UserTypes.References)value;

			((IDataParameter)cmd.Parameters[index]).Value = _references.Primary; 
			((IDataParameter)cmd.Parameters[index + 1]).Value = _references.Secondary; 
			((IDataParameter)cmd.Parameters[index + 2]).Value = _references.Tertiary; 
		}


		/// <summary>
		/// Deep copy
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public object DeepCopy(object value)
		{
			if (value == null)
			{
				return null;
			}

			return (epicenter2010.NH.Customisation.UserTypes.References)value;
		}


		/// <summary>
		/// Disassemble
		/// </summary>
		/// <param name="value"></param>
		/// <param name="session"></param>
		/// <returns></returns>
		public object Disassemble(object value, ISessionImplementor session)
		{
			return value;
		}


		/// <summary>
		/// Assemble
		/// </summary>
		/// <param name="cached"></param>
		/// <param name="session"></param>
		/// <param name="owner"></param>
		/// <returns></returns>
		public object Assemble(object cached, ISessionImplementor session, object owner)
		{
			return cached;
		}


		/// <summary>
		/// Replace
		/// </summary>
		/// <param name="original"></param>
		/// <param name="target"></param>
		/// <param name="session"></param>
		/// <param name="owner"></param>
		/// <returns></returns>
		public object Replace(object original, object target, ISessionImplementor session, object owner)
		{
			return original;
		}


		/// <summary>
		/// Property names
		/// </summary>
		public string[] PropertyNames
		{
			get { return new string[] { "Primary", "Secondary", "Tertiary" }; }
		}


		/// <summary>
		/// Property types
		/// </summary>
		public IType[] PropertyTypes
		{
			get
			{
				return new NHibernate.Type.IType[]
				    {
				       	NHibernateUtil.String,
				       	NHibernateUtil.String,
				       	NHibernateUtil.String
				    };
			}
		}


		/// <summary>
		/// Returned class
		/// </summary>
		public Type ReturnedClass { get { return typeof(epicenter2010.NH.Customisation.UserTypes.References); } }


		/// <summary>
		/// IsMutable
		/// </summary>
		public bool IsMutable { get { return false; } }
	}
}
